package com.mytest.filter;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Activate(group = CommonConstants.CONSUMER)
public class TPMonitorFilter implements Filter {
    public static Map<String,Set<MessageInfo>>  REQUEST_TIME = new ConcurrentHashMap<>();
    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long startTime = System.currentTimeMillis();
        try {
            return invoker.invoke(invocation);
        }finally {
            long endTime = System.currentTimeMillis();
            String methodName = invocation.getMethodName();
            Set<MessageInfo> messageInfos = REQUEST_TIME.get(methodName);
            //双重判断+加锁创建信息
            if (messageInfos==null){
                synchronized (REQUEST_TIME){
                    messageInfos = REQUEST_TIME.get(methodName);
                    if (messageInfos==null){
                        messageInfos = new HashSet<>();
                        REQUEST_TIME.put(methodName,messageInfos);
                    }
                }
            }
            //记录调用耗时时间和结束时间戳
            messageInfos.add(new MessageInfo(endTime-startTime,endTime));
        }
    }
    //创建一个内部类 实现Comparable接口 防止使用lambda表达式转流时报错
    public static class MessageInfo implements Comparable<MessageInfo>{
        private long time;
        private long endTime;

        public MessageInfo(long time, long endTime) {
            this.time = time;
            this.endTime = endTime;
        }

        public long getTime() {
            return time;
        }

        public long getEndTime() {
            return endTime;
        }

        @Override
        public int compareTo(MessageInfo o) {
            return (int) (this.time-o.getTime());
        }
    }
}
